﻿//MarketDataEnumerator.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Algo.Storages
{
	using System;
	using System.Collections.Generic;

	using Ecng.Collections;

	interface IMarketDataEnumerator<TData> : IEnumerator<TData>
	{
		TData Previous { get; }
		TData Delta { get; }
	}

	class MarketDataEnumerator<TData, TMetaInfo> : SimpleEnumerator<TData>, IMarketDataEnumerator<TData> 
			where TMetaInfo : MetaInfo<TMetaInfo>
	{
		private readonly TMetaInfo _originalMetaInfo;

		public MarketDataEnumerator(MarketDataSerializer<TData, TMetaInfo> serializer, DateTime date, OptimizedBitArrayReader reader, TMetaInfo metaInfo)
		{
			if (serializer == null)
				throw new ArgumentNullException("serializer");

			if (reader == null)
				throw new ArgumentNullException("reader");

			if (metaInfo == null)
				throw new ArgumentNullException("metaInfo");

			Serializer = serializer;
			Index = -1;
			Date = date;
			Reader = reader;

			_originalMetaInfo = metaInfo;
		}

		public OptimizedBitArrayReader Reader { get; private set; }

		public TMetaInfo MetaInfo { get; private set; }

		public MarketDataSerializer<TData, TMetaInfo> Serializer { get; private set; }

		public int Index { get; private set; }

		public int PartSize { get; private set; }

		public DateTime Date { get; private set; }

		public TData Previous { get; private set; }

		public TData Delta { get; internal set; }

		public override bool MoveNext()
		{
			if (Reader == null)
				return false;

			if (Index < 0) // enumerator стоит перед первой записью
			{
				MetaInfo = _originalMetaInfo.Clone();
				Index = 0;
			}

			if (Index >= MetaInfo.Count)
				return false;

			if (Index == PartSize)
				PartSize += Reader.DeserializeInt();

			Current = Serializer.MoveNext(this);
			Previous = Current;

			if (Index == (PartSize - 1))
			{
				Reader.AlignReader();
			}

			Index++;

			return true;
		}

		public override void Reset()
		{
			Index = -1;
			MetaInfo = null;
			Previous = Current = default(TData);
			PartSize = 0;

			if (Reader != null)
				Reader.Offset = 0;
		}
	}
}